/**
 *  This file is part of TaoBaoItemImporter.
 *
 *   TaoBaoItemImporter is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   TaoBaoItemImporter is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with TaoBaoItemImporter.  If not, see <http://www.gnu.org/licenses/>. 
 */
package com.googlecode.ulysses.taobao.importer;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import org.bson.types.ObjectId;

import com.google.gson.Gson;
import com.googlecode.ulysses.taobao.Constants;
import com.googlecode.ulysses.taobao.ItemMongoWriter;
import com.googlecode.ulysses.taobao.Parser;
import com.googlecode.ulysses.taobao.data.Item;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;

/**
 * A base class for constructing an item object.
 * 
 * This class only implements
 * <em>addItemMainToCollection(DBCollection coll, Item item)</em> method. All
 * derived classes should implement some of the rest.
 * 
 * @author Ulysses <robman1070@gmail.com>
 * 
 */
abstract class ItemImporter implements ItemMongoWriter, Parser {

	protected Item item = null;
	protected Gson gson = new Gson();
	protected DateFormat df = new SimpleDateFormat(
			Constants.DEFAULT_DATE_FORMAT_PATTERN);
	protected BasicDBObject doc = new BasicDBObject();

	// protected CreateCPSLink cpslink = new CreateCPSLink();

	/**
	 * Return if the item is sold out.
	 * 
	 * @param item
	 *            An item object
	 * @return true if num is larger than 0; false otherwise
	 */
	public boolean isSoldOut(Item item) {
		return item.getItem_get_response().getItem().getNum() > 0 ? false
				: true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.ulysses.taobao.ItemMongoWriter#importItemToCollection(
	 * com.mongodb.DBCollection, com.googlecode.ulysses.taobao.data.Item)
	 */
	public void importItemToCollection(DBCollection coll, Item item) {
		addItemMainToCollection(coll, item);
		addItemPropertyToCollection(coll, item);
		addItemBuyLinkToCollection(coll, item);
		addItemFieldToCollection(coll, item);
		updateItemFieldToCollection(coll, item);
		addAndUpdateItemFieldToCollection(coll, item);

		write(coll);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.ulysses.taobao.ItemImporter#addItemMainToCollection(com
	 * .mongodb.DBCollection, com.googlecode.ulysses.taobao.data.Item)
	 */
	@Override
	public DBCollection addItemMainToCollection(DBCollection coll, Item item) {
		/* Write the main part of an item object to a collection object. */
		doc.put("item_name", item.getItem_get_response().getItem().getTitle());
		doc.put("user_name", Constants.ADMIN_USER);
		doc.put("price_range_start", item.getItem_get_response().getItem().getPrice());
		doc.put("price_range_end", item.getItem_get_response().getItem().getPrice());
		doc.put("item_rating", Constants.DEFAULT_ITEM_RATING);
		doc.put("num_rating", Constants.DEFAULT_NUM_RATING);
		doc.put("item_main_cats", Constants.DEFAULT_ITEM_MAIN_CATS); // This will be overwritten by a derived class
		doc.put("item_sub_cats", Constants.PROP_MAPPING.getCategory_mapping().get(new Long(item.getItem_get_response().getItem().getCid())).intValue()); // FIXME can be broken if category not found in the map
		doc.put("created_on", item.getItem_get_response().getItem().getCreated().toString());
		doc.put("time_zone", Constants.DEFAULT_TIME_ZONE);
		doc.put("image_small_path", item.getItem_get_response().getItem().getPic_url()); // FIXME perhaps there is a better one in image list by getItem_imgs()
		doc.put("image_middle_path", item.getItem_get_response().getItem().getPic_url()); // FIXME perhaps there is a better one in image list by getItem_imgs()
		doc.put("image_big_path", item.getItem_get_response().getItem().getPic_url()); // FIXME perhaps there is a better one in image list by getItem_imgs()
		doc.put("item_brand", Constants.NOT_AVAILABLE); // FIXME information is in the props_name and props fields
		
		/* Those whose value is an array */
		doc.put("item_reviews", new ArrayList<ObjectId>());
		doc.put("rating_details", new ArrayList<ObjectId>());
		
		/* Information for internal use, such as where are the data from, identification, etc. */
		BasicDBObject adminProperties = new BasicDBObject();
		adminProperties.put("source", Constants.DEFAULT_ITEM_SOURCE);
		adminProperties.put("num_iid", String.valueOf(item.getItem_get_response().getItem().getNum_iid()));
		doc.put("admin_properties", adminProperties); 
		
		return coll;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.ulysses.taobao.ItemImporter#write(com.mongodb.DBCollection
	 * )
	 */
	@Override
	public void write(DBCollection coll) {
		coll.insert(doc);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.googlecode.ulysses.taobao.Parser#jsonToItem(java.lang.String)
	 */
	public Item jsonToItem(String jsonStr) {
		item = gson.fromJson(jsonStr, Item.class);
		return item;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.ulysses.taobao.ItemMongoWriter#addAndUpdateItemToCollection
	 * (com.mongodb.DBCollection, com.googlecode.ulysses.taobao.data.Item)
	 */
	@Override
	public DBCollection addAndUpdateItemFieldToCollection(DBCollection coll,
			Item item) {
		// Do nothing. The derived classes who wish to add/update fields should
		// override this method.
		return coll;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.ulysses.taobao.ItemMongoWriter#addItemToCollection(com
	 * .mongodb.DBCollection, com.googlecode.ulysses.taobao.data.Item)
	 */
	@Override
	public DBCollection addItemFieldToCollection(DBCollection coll, Item item) {
		return addAndUpdateItemFieldToCollection(coll, item);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.ulysses.taobao.ItemMongoWriter#updateItemToCollection(
	 * com.mongodb.DBCollection, com.googlecode.ulysses.taobao.data.Item)
	 */
	@Override
	public DBCollection updateItemFieldToCollection(DBCollection coll, Item item) {
		return addAndUpdateItemFieldToCollection(coll, item);
	}

}
